package com.zys.http.processor.basic;

import cn.hutool.core.text.CharSequenceUtil;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ResourceFileUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.zys.http.tool.ThreadTool;
import jdk.jfr.Description;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.yaml.YAMLUtil;
import org.jetbrains.yaml.psi.YAMLFile;

import java.util.List;
import java.util.Objects;

/**
 * @author zys
 * @since 2025-01-13
 */
public interface ModuleProcessor {
    String[] APPLICATION_FILE_NAMES = {
            "bootstrap.properties", "bootstrap.yaml", "bootstrap.yml",
            "application.properties", "application.yaml", "application.yml"
    };
    String CONTEXT_PATH_KEY = "server.servlet.context-path";
    String PORT_KEY = "server.port";

    /**
     * 获取模块中的 controller
     *
     * @param module 模块
     * @return /
     */
    List<? extends PsiElement> moduleControllers(Module module, Project project);

    @SneakyThrows
    @Description("获取模块中的 SpringBoot 优先级最高的配置文件")
    default PsiFile moduleSpringBootApplicationFile(Module module, Project project) {
        PsiManager psiManager = PsiManager.getInstance(project);
        return ReadAction.nonBlocking(() -> {
            for (String applicationFileName : APPLICATION_FILE_NAMES) {
                VirtualFile file = ResourceFileUtil.findResourceFileInScope(applicationFileName, project, module.getModuleScope());
                if (Objects.nonNull(file)) {
                    return psiManager.findFile(file);
                }
            }
            return null;
        }).submit(ThreadTool.getExecutor()).get();
    }

    @SneakyThrows
    @Description("获取模块中配置文件中指定键的值")
    default String modulePropertyValue(Module module, Project project, String key) {
        if (CharSequenceUtil.isEmpty(key)) {
            return "";
        }
        PsiFile psiFile = moduleSpringBootApplicationFile(module, project);
        if (Objects.isNull(psiFile)) {
            return "";
        }
        if (psiFile instanceof YAMLFile yamlFile) {
            Pair<PsiElement, String> value = ReadAction.nonBlocking(() -> YAMLUtil.getValue(yamlFile, key.split("\\.")))
                    .submit(ThreadTool.getExecutor()).get();
            if (Objects.nonNull(value)) {
                PsiElement first = value.getFirst();
                String text = first.getText();
                return text.split(":")[0].trim();
            }
        }
        if (psiFile instanceof PropertiesFile propertiesFile) {
            return ReadAction.nonBlocking(() -> propertiesFile.getNamesMap().getOrDefault(key, "")).submit(ThreadTool.getExecutor()).get();
        }

        return "";
    }

    default String modulePath(Module module, Project project) {
        return modulePropertyValue(module, project, CONTEXT_PATH_KEY);
    }

    default String modulePort(@NotNull Module module, Project project) {
        String port = modulePropertyValue(module, project, PORT_KEY);
        return CharSequenceUtil.isEmpty(port) ? "8080" : port;
    }

    default String getGradleParentModuleName(Module module) {
        if (module == null) {
            return null;
        }
        String moduleName = module.getName();
        if (!moduleName.endsWith(".main")) {
            return null;
        }

        VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
        if (contentRoots.length == 0) {
            return null;
        }
        // 判断当前模块的目录
        VirtualFile currentModuleDir = contentRoots[0];
        String currentModulePath = currentModuleDir.getCanonicalPath();
        if (currentModulePath == null) {
            return null;
        }
        if (!currentModulePath.endsWith("/src/main")) {
            return null;
        }

        // 判断父目录
        VirtualFile parent = currentModuleDir.getParent();
        String parentModuleName = moduleName.substring(0, moduleName.length() - ".main".length());
        String parentPath = parent.getCanonicalPath();
        if (parentPath == null) {
            return null;
        }
        if (!parentPath.endsWith(parentModuleName + "/src")) {
            return null;
        }

        return parentModuleName;
    }
}
